//
//  WSWebViewController.m
//  MurderMystery
//
//  Created by administrator on 2018/8/9.
//  Copyright © 2018年 luomz. All rights reserved.
//

#import "WSWebViewController.h"
#import "NSTimer+Addition.h"
#import "WebProgressLayer.h"
#import <WSConst.h>
#import <WSViewActionProtocol.h>

//window.webkit.messageHandlers.Back.postMessage  js通知App要调用的方法


@interface WSWebViewController ()< WSViewActionProtocol,WKNavigationDelegate,WKUIDelegate,WKScriptMessageHandler,UIGestureRecognizerDelegate>

@property (nonatomic,copy)NSString * rightTitle;
@property (nonatomic, strong)WebProgressLayer *webProgressLayer;

@property (nonatomic,strong,readwrite) UIBarButtonItem *returnButton;
@property (nonatomic,strong,readwrite) UIBarButtonItem *closeItem;

@property (nonatomic, strong) UIView          *errorView;

@property (nonatomic)BOOL isShowClose;

@property (copy,nonatomic) NSString * qrCodeString;

@end

@implementation WSWebViewController

- (void)viewDidDisappear:(BOOL)animated {
    [[self class] cancelPreviousPerformRequestsWithTarget:self];
    [super viewDidDisappear:animated];
}

- (BOOL)forbidPanBack {return YES;}

- (NSString *)urlValueEncode:(NSString *)str
{
    NSString *result = (NSString*) CFBridgingRelease(CFURLCreateStringByAddingPercentEscapes(kCFAllocatorDefault,(CFStringRef)str,(CFStringRef)@"!$&'()*+,-./:;=?@_~%#[]",NULL, kCFStringEncodingUTF8));
    return result;
}

- (void)viewDidLoad {
    [super viewDidLoad];
//    self.view.backgroundColor = [UIColor whiteColor];
    
    
//    [ShareClass cleanWebViewCache];
    self.view.backgroundColor = kUIColorWithRGB(0xf0f0f0);
    
    self.automaticallyAdjustsScrollViewInsets = NO;
    self.title = self.webTitle;
    
    if (![self.url hasPrefix:@"http"]) {
        self.url = [NSString stringWithFormat:@"http://%@",self.url];
    }
    //    self.url = [self.url stringByAddingPercentEscapesUsingEncoding:NSUTF8StringEncoding];
    self.url = [self urlValueEncode:_url];
    
    [self setUpUI];
}

- (void)setUpUI {
    
    WKUserContentController *userContentController = [[WKUserContentController alloc] init];
    
    WKWebViewConfiguration *configuration = [[WKWebViewConfiguration alloc] init];
    //允许视频播放
        if (@available(iOS 9.0, *)) {
            configuration.allowsAirPlayForMediaPlayback = YES;
        } else {
            // Fallback on earlier versions
        }

    configuration.allowsInlineMediaPlayback = YES;
    configuration.selectionGranularity = YES;
    configuration.suppressesIncrementalRendering = YES;
    configuration.userContentController = userContentController;

    //注册js方法
    NSMutableArray * functions = [NSMutableArray arrayWithArray:[self jsGlobalFunctions]];
    if ([self jsCustomFunctions].count > 0)
        [functions addObjectsFromArray:[self jsCustomFunctions]];
    if ([functions count] > 0) {
        for (NSString * name in functions) {
            [configuration.userContentController addScriptMessageHandler:[[WeakScriptMessageDelegate alloc] initWithDelegate:self] name:name];
        }
    }

    WKWebView * webView = [[WKWebView alloc] initWithFrame:self.view.bounds configuration:configuration];
    
    if (self.view.height == WScreenHeight) {
        webView.height = WScreenHeight - kNavbarHeight;
    }
    
    webView.navigationDelegate =self;
    webView.UIDelegate = self;
    webView.allowsBackForwardNavigationGestures = YES;
    NSURLRequest *request = [NSURLRequest requestWithURL:[NSURL URLWithString:self.url] cachePolicy:NSURLRequestUseProtocolCachePolicy timeoutInterval:30];
    [webView loadRequest:request];
    
    self.wsWebView = webView;
    
    [self addObserver];

    UILongPressGestureRecognizer *longPress = [[UILongPressGestureRecognizer alloc] initWithTarget:self action:@selector(handleLongPress:)];
    longPress.minimumPressDuration = .2;
    longPress.delegate = self;
    [webView addGestureRecognizer:longPress];
    
    [self.view addSubview:webView];
    
    
    WebProgressLayer * progressLayer = [[WebProgressLayer alloc] init];
    progressLayer.frame = CGRectMake(0, 42, WIDTH, 2);
    progressLayer.strokeColor = self.progressColor.CGColor;
    [self.navigationController.navigationBar.layer addSublayer:progressLayer];
    self.webProgressLayer = progressLayer;
    
}

- (NSArray *)jsCustomFunctions {
    return nil;
}

- (void)addObserver
{
    [self.wsWebView addObserver:self
                     forKeyPath:@"estimatedProgress"
                        options:NSKeyValueObservingOptionNew
                        context:nil];
    
    [self.wsWebView addObserver:self
                     forKeyPath:@"canGoBack"
                        options:NSKeyValueObservingOptionNew
                        context:nil];
    
    [self.wsWebView addObserver:self
                     forKeyPath:@"title"
                        options:NSKeyValueObservingOptionNew
                        context:NULL];
}

#pragma mark - KVO

- (void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary *)change context:(void *)context
{
    if (object == self.wsWebView) {
        if ([keyPath isEqualToString:@"estimatedProgress"]) {
            CGFloat progress = [[change objectForKey:NSKeyValueChangeNewKey] doubleValue];
            if (progress == 1) {
                [self.webProgressLayer finishedLoadWithError:nil];
            } else {
                [self.webProgressLayer startLoad];
            }
        } else if ([keyPath isEqualToString:@"canGoBack"]) {
            [self updateButtonItems];
            
        } else if ([keyPath isEqualToString:@"title"]) {
            self.title = self.wsWebView.title;
        }
    }
}
- (void)updateButtonItems {
    if (self.wsWebView.canGoBack) {
        [self showCloseButton];
    }
    else {
        self.navigationItem.leftBarButtonItems = @[self.returnButton];
        _isShowClose = NO;
    }
}

#pragma mark - Action
- (void)closeButtonAction {
    [self.webProgressLayer removeFromSuperlayer];
    [self.navigationController popViewControllerAnimated:YES];
}

- (void)showCloseButton {
    if (_isShowClose == NO) {
        self.navigationItem.leftBarButtonItems = @[self.returnButton, self.closeItem];
        _isShowClose = YES;
    }
}

- (void)backAction {
    [self.webProgressLayer removeFromSuperlayer];
    if ([self.wsWebView canGoBack]) {
        [self.wsWebView goBack];
    }else {
        [super backAction];
    }
    
}

#pragma mark ----------UKUIDelegate
-(WKWebView *)webView:(WKWebView *)webView createWebViewWithConfiguration:(WKWebViewConfiguration *)configuration forNavigationAction:(WKNavigationAction *)navigationAction windowFeatures:(WKWindowFeatures *)windowFeatures
{
    if (!navigationAction.targetFrame.isMainFrame) {
        [webView loadRequest:navigationAction.request];
    }
    return nil;
}

- (void)webView:(WKWebView *)webView runJavaScriptAlertPanelWithMessage:(NSString *)message initiatedByFrame:(WKFrameInfo *)frame completionHandler:(void (^)(void))completionHandler
{
    UIAlertController *alertVC = [UIAlertController alertControllerWithTitle:@"温馨提示" message:message preferredStyle:UIAlertControllerStyleAlert];
    UIAlertAction *confirmAction = [UIAlertAction actionWithTitle:@"确定" style:UIAlertActionStyleDefault handler:nil];
    [alertVC addAction:confirmAction];
    [self presentViewController:alertVC animated:YES completion:nil];
    completionHandler();
}

- (void)webViewWebContentProcessDidTerminate:(WKWebView *)webView {
    [webView reload];
}

#pragma mark - WKScriptMessageHandler
- (void)userContentController:(WKUserContentController *)userContentController didReceiveScriptMessage:(WKScriptMessage *)message {
    NSString *methods = [NSString stringWithFormat:@"%@:",message.name];
    SEL selector = NSSelectorFromString(methods);
    // 调用方法
    if ([self respondsToSelector:selector]) {
        [self performSelector:selector withObject:message.body];
    } else {
        NSLog(@"未实现方法：%@", methods);
    }
}

- (void)webView:(WKWebView *)webView didReceiveAuthenticationChallenge:(NSURLAuthenticationChallenge *)challenge completionHandler:(void (^)(NSURLSessionAuthChallengeDisposition, NSURLCredential * _Nullable))completionHandler {
    if ([challenge.protectionSpace.authenticationMethod isEqualToString:NSURLAuthenticationMethodServerTrust]) {
        
        NSURLCredential *card = [[NSURLCredential alloc]initWithTrust:challenge.protectionSpace.serverTrust];
        
        completionHandler(NSURLSessionAuthChallengeUseCredential,card);
        
    }
}

//全局的js回调方法
- (NSArray *)jsGlobalFunctions {
    return @[@"getToken",@"getAppVersionName",@"getUUId",@"getPhoneModel",@"getClientId"];
}
#pragma mark - js调用方法
- (void)getToken:(id)data {
//    NSString *token = UserDataHandler.getUserInfo.token;
//    NSString * jsStr  =[NSString stringWithFormat:@"getToken('%@')",token];
//    [self.wsWebView evaluateJavaScript:jsStr completionHandler:nil];
}
- (void)getAppVersionName:(id)data {
//    NSString * version = [[UIApplication sharedApplication] appVersion];
//    NSString * jsStr  =[NSString stringWithFormat:@"getAppVersionName('%@')",version];
//    [self.wsWebView evaluateJavaScript:jsStr completionHandler:nil];
}
- (void)getUUId:(id)data {
//    NSString *deviceId = [DobestDeviceInfo getDeviceId];
//    NSString * jsStr  =[NSString stringWithFormat:@"getUUId('%@')",deviceId];
//    [self.wsWebView evaluateJavaScript:jsStr completionHandler:nil];
}
- (void)getPhoneModel:(id)data {
//    NSString * jsStr  =[NSString stringWithFormat:@"getPhoneModel('%@')",[UIDevice deviceName] ];
//    [self.wsWebView evaluateJavaScript:jsStr completionHandler:nil];
}
- (void)getClientId:(id)data {
//    NSString *getuiClintId = GetuiHelper.sharedInstance.getuiClientId;
//    NSString * jsStr  =[NSString stringWithFormat:@"getClientId('%@')",getuiClintId];
//    [self.wsWebView evaluateJavaScript:jsStr completionHandler:nil];
}

#pragma mark - WKNavigationDelegate
- (void)webView:(WKWebView *)webView didStartProvisionalNavigation:(WKNavigation *)navigation {
    [self.webProgressLayer startLoad];
}

- (void)webView:(WKWebView *)webView didFinishNavigation:(WKNavigation *)navigation {
    [self.wsWebView evaluateJavaScript:@"document.documentElement.style.webkitTouchCallout='none';" completionHandler:nil];
    [self.wsWebView evaluateJavaScript:@"document.documentElement.style.webkitUserSelect='none';"completionHandler:nil];
    [self.webProgressLayer finishedLoadWithError:nil];
}

- (void)webView:(WKWebView *)webView didFailProvisionalNavigation:(WKNavigation *)navigation withError:(NSError *)error {
    [self.webProgressLayer finishedLoadWithError:error];
    [self setErrorViewHidden:NO];
    self.title = @"加载失败";
}

- (void)setErrorViewHidden:(BOOL)hidden
{
    if (hidden) {
        [self.errorView removeFromSuperview];
    } else {
        [self.view addSubview:self.errorView];
    }
}

- (void)refreshPage {
    [self.wsWebView reload];
}

#pragma mark - private
//- (BOOL)forbidPanBack {
//    return [self.wsWebView canGoBack];
//}
- (UIColor *)progressColor {
    return _progressColor ?: kAppMainColor;
}

- (UIBarButtonItem *)returnButton {
    if (!_returnButton) {
        _returnButton = [[UIBarButtonItem alloc] init];
        UIButton *button = [UIButton buttonWithType:UIButtonTypeCustom];
        UIImage *image = WSImage(@"icon_back");
        
        [button setImage:image forState:UIControlStateNormal];//这是一张“<”的图片
        [button addTarget:self action:@selector(backAction) forControlEvents:UIControlEventTouchUpInside];
        button.contentEdgeInsets = UIEdgeInsetsMake(0, -15, 0, 0);
        button.frame = CGRectMake(20, 0, 40, 40);
        _returnButton.customView = button;
        self.navigationItem.leftBarButtonItem = _returnButton;
    }
    return _returnButton;
}

- (UIBarButtonItem *)closeItem {
    if (!_closeItem) {
        _closeItem = [[UIBarButtonItem alloc] initWithTitle:@"关闭" style:UIBarButtonItemStyleDone target:self action:@selector(closeButtonAction)];
        _closeItem.tintColor = kAppMainColor;
    }
    return _closeItem;
}

- (UIView *)errorView
{
    if (!_errorView) {
        _errorView = [[UIView alloc] initWithFrame:self.view.bounds];
        _errorView.autoresizingMask = UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleHeight;
        _errorView.backgroundColor = [UIColor whiteColor];
        UITapGestureRecognizer *gesture = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(refreshPage)];
        _errorView.userInteractionEnabled = YES;
        [_errorView addGestureRecognizer:gesture];
        UIButton *button = [[UIButton alloc] initWithFrame:CGRectMake(0, 0, 140, 60)];
        [button setTitle:@"轻触重新加载" forState:UIControlStateNormal];
        [button setTitleColor:[UIColor lightGrayColor] forState:UIControlStateNormal];
        [button addTarget:self action:@selector(refreshPage) forControlEvents:UIControlEventTouchUpInside];
        button.center = _errorView.center;
        [_errorView addSubview:button];
    }
    
    return _errorView;
}

- (void)dealloc {
    [self.webProgressLayer closeTimer];
    [_webProgressLayer removeFromSuperlayer];
    _webProgressLayer = nil;
    
    [_wsWebView removeObserver:self forKeyPath:@"estimatedProgress"];
    [_wsWebView removeObserver:self forKeyPath:@"canGoBack"];
    [_wsWebView removeObserver:self forKeyPath:@"title"];
    
    NSMutableArray * functions = [NSMutableArray arrayWithArray:[self jsGlobalFunctions]];
    if ([self jsCustomFunctions].count > 0)
        [functions addObjectsFromArray:[self jsCustomFunctions]];
    for (NSString * funcName in functions) {
        [_wsWebView.configuration.userContentController removeScriptMessageHandlerForName:funcName];
    }
}
@end

@implementation WeakScriptMessageDelegate

- (instancetype)initWithDelegate:(id<WKScriptMessageHandler>)scriptDelegate {
    self = [super init];
    if (self) {
        _scriptDelegate = scriptDelegate;
    }
    return self;
}

- (void)userContentController:(WKUserContentController *)userContentController didReceiveScriptMessage:(WKScriptMessage *)message {
    [self.scriptDelegate userContentController:userContentController didReceiveScriptMessage:message];
}

@end







